# -*- coding: utf-8 -*-
import binascii
import sys

from PySide6.QtCore import Signal, Qt, QTimer, QThread, QDateTime
from PySide6.QtGui import QKeySequence, QShortcut, QColor, QFont
from PySide6.QtWidgets import QMainWindow, QMessageBox, QApplication, QTableWidgetItem, QFileDialog
from loguru import logger

from utils.csvHandler import CsvHandler
from utils.timeUtils import DelayMilliseconds
from windowUI.iICBatchProcess_ui import Ui_IICBatchProcessMainWindow


class BatchWorkerThread(QThread):
    dataSignal = Signal(dict)
    csvHandler: CsvHandler = None
    maxOperateCount = 0
    timeDelay = 0

    def __init__(self):
        super().__init__()
        self.is_running = False

    def HandleData(self):
        # 过滤表头
        row_idx = -2
        for rowList in self.csvHandler.runData:
            col_idx = 0
            dataDict = {}
            row_idx += 1
            for col_value in rowList:
                if col_idx == 0:
                    if ("Y" in col_value) or ("y" in col_value):
                        dataDict.update({"checkState": col_value})
                        dataDict.update({"msg_id": row_idx})
                    else:
                        break
                elif col_idx == 1:
                    dataDict.update({"shortName": col_value})
                elif col_idx == 2:
                    dataDict.update({"operation": col_value})
                elif col_idx == 3:
                    dataDict.update({"slaveAddr": col_value})
                elif col_idx == 4:
                    dataDict.update({"cmd_addr": col_value})
                elif col_idx == 5:
                    dataDict.update({"data_len": col_value})
                elif col_idx == 6:
                    dataDict.update({"timeDalay": col_value})
                    DelayMilliseconds(int(col_value))
                elif col_idx == 7:
                    dataDict.update({"dataType": col_value})
                elif col_idx == 8:
                    dataDict.update({"expectData": col_value})
                elif col_idx == 9:
                    dataDict.update({"remark": col_value})
                col_idx += 1
            if dataDict:
                self.dataSignal.emit(dataDict)

    def run(self):
        logger.debug("Thread started")
        if not self.is_running:
            return
        while self.maxOperateCount > 0:
            self.HandleData()
            DelayMilliseconds(int(self.timeDelay))
            self.maxOperateCount -= 1
            logger.debug(f"剩余执行次数: {self.maxOperateCount}")
        logger.debug("Thread finished")
        self.is_running = False
        self.exit()


class IICBatchProcessWindow(QMainWindow, Ui_IICBatchProcessMainWindow):
    """
    IIC批处理
    """
    # 声明带一个字典类型参数的信号
    iICBatchProcessSignal = Signal(dict)
    script_path = None

    def __init__(self):
        super().__init__()
        # 加载UI
        self.setupUi(self)
        # 连接信号与槽
        self.SignalConnectInit()
        # 创建定时器
        self.TimerInit()
        # 添加快捷键
        self.ShortcutFun()
        # 引入公共程序
        from utils.common import commonProgram
        # 引入配置文件
        self.myConfig = commonProgram.EnableConfigHandler()
        logger.info('IICBatchProcessMainWindow get config Version', self.myConfig.version)
        # 引入可控设备信息窗口
        self.ft4222Win = commonProgram.EnableFt4222(winSignal=self.iICBatchProcessSignal,
                                                    RecvFt4222Data=self.RecvFt4222Data)
        # 初始化脚本
        self.ScriptInit()
        self.batchWorkerThread = BatchWorkerThread()
        self.batchWorkerThread.csvHandler = self.csvHandler
        self.batchWorkerThread.dataSignal.connect(self.ScriptProcessFun)
        self.batchWorkerThread.maxOperateCount = self.spinBoxOperateCount.value()

    def CleanupSelf(self):
        """
        清理当前窗口并关闭，由其他其他程序调用
        :return:
        """
        try:
            # 停止并注销定时器
            # self.timer_operate.stop()
            # self.timer_operate.deleteLater()
            self.close()  # 关闭当前窗口
            self.deleteLater()  # 释放子窗口资源
            logger.debug("PluginWindow.__del__.ok")
        except Exception as err:
            logger.debug("PluginWindow.__del__.error", err)

    def SignalConnectInit(self):
        """
        连接来自UI对象的信号与槽
        :return:
        """
        # QPushButton
        self.btnOpenScript.clicked.connect(self.OpenScriptFun)
        self.btnSaveScript.clicked.connect(self.SaveScriptFun)
        self.btnSaveAsScript.clicked.connect(self.SaveAsScriptFun)
        self.btnAddScript.clicked.connect(self.AddScriptFun)
        self.btnDeleteScript.clicked.connect(self.DeleteScriptFun)
        self.btnOperateScript.clicked.connect(self.OperateScriptFun)
        self.btnRefreshScript.clicked.connect(self.RefreshScriptFun)
        self.btnCleanAllScript.clicked.connect(self.CleanAllScriptFun)
        # QCheckBox
        self.checkBoxTimerOperate.stateChanged.connect(self.TimerOperateFun)
        self.checkBoxSelectAll.stateChanged.connect(self.SelectAllFun)
        # 连接 cellClicked 信号
        self.tableWidget.cellClicked.connect(self.OnCellClicked)
        # 连接 cellChanged 信号
        self.tableWidget.cellChanged.connect(self.OnCellChanged)

    def ScriptInit(self):
        self.csvHandler = CsvHandler()
        self.csvHandler.horizontalHeaderCount = self.tableWidget.columnCount()
        # 获取列名
        for col in range(self.tableWidget.columnCount()):
            self.csvHandler.horizontalHeaderList.append(self.tableWidget.horizontalHeaderItem(col).text())
        logger.debug("Column Names:", self.csvHandler.horizontalHeaderList)

        self.csvHandler.runData.append(self.csvHandler.horizontalHeaderList)

        self.csvHandler.verticalHeaderCount = self.tableWidget.rowCount()
        # 获取行名
        # row_names = []
        # for row in range(self.tableWidget.rowCount()):
        #     row_names.append(self.tableWidget.verticalHeaderItem(row).text())
        # print("Row Names:", row_names)
        dictData = {"checkState": "yes", "shortName": "使能控制", "operation": "ctrl", "slaveAddr": "",
                    "cmd_addr": "gpio2", "data_len": "1", "timeDalay": "1000", "dataType": "", "remark": "控制指令示例",
                    "expectData": ""}
        self.AddScriptData(dataDict=dictData)
        dictData = {"checkState": "yes", "shortName": "写backlight", "operation": "write", "slaveAddr": "0x77",
                    "cmd_addr": "03", "data_len": "4B 00 00 00 00 00 48", "timeDalay": "100", "dataType": "hex",
                    "remark": "写指令示例", "expectData": ""}
        self.AddScriptData(dataDict=dictData)
        dictData = {"checkState": "yes", "shortName": "读backlight", "operation": "read", "slaveAddr": "0x77",
                    "cmd_addr": "02", "data_len": "10", "timeDalay": "100", "dataType": "hex", "remark": "读指令示例",
                    "expectData": "02 4B"}
        self.AddScriptData(dataDict=dictData)

    def ScriptProcessFun(self, dictData: dict):
        operation = dictData.get("operation", "").lower()
        if "w" in operation:
            self.HandSendFun(dictData)
        elif "c" in operation:
            self.HandCtrlFun(dictData)
        else:
            self.HandReadFun(dictData)
        # dictData = {"data": dictData, "type": f"IICBatchProcess_to_Main_call_ScriptProcessFun"}
        # self.SendDataHandle(dictData)

    def AddScriptData(self, dataDict: dict):
        listData = [dataDict.get("checkState", ""), dataDict.get("shortName"), dataDict.get("operation", ""),
                    dataDict.get("slaveAddr", ""), dataDict.get("cmd_addr", ""), dataDict.get("data_len", ""),
                    dataDict.get("timeDalay", int), dataDict.get("dataType", "hex"), dataDict.get("expectData", ""),
                    dataDict.get("remark", "")]
        self.csvHandler.runData.append(listData)

        checkState = Qt.CheckState.PartiallyChecked
        if ("Y" in listData[0]) or ("y" in listData[0]):
            checkState = Qt.CheckState.Checked
        elif ("N" in listData[0]) or ("n" in listData[0]):
            checkState = Qt.CheckState.Unchecked
        tableWidgetItem = QTableWidgetItem(listData[0])
        tableWidgetItem.setCheckState(checkState)
        # 将备注信息加入第一行提示
        tableWidgetItem.setToolTip(listData[9])
        # 禁止编辑，可以选择
        tableWidgetItem.setFlags(Qt.ItemFlag.ItemIsEnabled | Qt.ItemFlag.ItemIsUserCheckable)

        row_position = self.tableWidget.rowCount()
        self.tableWidget.insertRow(row_position)
        self.tableWidget.setItem(row_position, 0, tableWidgetItem)
        self.tableWidget.setItem(row_position, 1, QTableWidgetItem(listData[1]))

        itemColor = QColor(51, 255, 255, 255)
        if ("W" in listData[2]) or ("w" in listData[2]):
            itemColor = QColor(255, 255, 51, 255)
        elif ("C" in listData[2]) or ("c" in listData[2]):
            itemColor = QColor(255, 126, 51, 255)
        tableWidgetItem = QTableWidgetItem(listData[2])
        tableWidgetItem.setBackground(itemColor)
        self.tableWidget.setItem(row_position, 2, tableWidgetItem)

        self.tableWidget.setItem(row_position, 3, QTableWidgetItem(listData[3]))
        self.tableWidget.setItem(row_position, 4, QTableWidgetItem(listData[4]))
        self.tableWidget.setItem(row_position, 5, QTableWidgetItem(str(listData[5])))
        self.tableWidget.setItem(row_position, 6, QTableWidgetItem(listData[6]))
        self.tableWidget.setItem(row_position, 7, QTableWidgetItem(listData[7]))
        self.tableWidget.setItem(row_position, 8, QTableWidgetItem(listData[8]))
        self.tableWidget.setItem(row_position, 9, QTableWidgetItem(listData[9]))

    def TimerInit(self):
        """
        定时器创建与信号连接
        此处添加了定时器，一定要在 `CleanupSelf`中添加注销操作，否则切换测试项时不会失效，会一直以子线程运行
        :return:
        """
        pass
        # self.timer_operate = QTimer()
        # self.timer_operate.timeout.connect(self.HandOperateFun)

    def ShortcutFun(self):
        """
        快捷键 F11 全屏
        快捷键 F5 清屏
        :return:
        """
        # 快捷键 F11
        self.screenStatus = 'Normal'
        screenShortcut = QShortcut(QKeySequence(Qt.Key_F11), self)
        screenShortcut.activated.connect(self.WindowSizeFun)
        self.setToolTip('全屏与退出全屏：\n               双击 或者 F11')
        # 快捷键 F5
        # screenShortcut2 = QShortcut(QKeySequence(Qt.Key_F5), self)
        # screenShortcut2.activated.connect(self.CleanFun)

    def WindowSizeFun(self):
        """
        控制窗口尺寸，此处为原大小（最小UI布局）或者全屏
        :return:
        """
        if self.screenStatus == 'Normal':
            self.showFullScreen()
            self.screenStatus = 'FullScreen'
        else:
            self.showNormal()
            self.screenStatus = 'Normal'

    def SendDataHandle(self, dataDict: dict):
        """
        发送信号或数据处理函数
        :param dataDict:
        :return:
        """
        # 发送信号处理
        dataObj = dataDict.get('data', '')
        typeValue = dataDict.get('type', 'null').strip()
        # 本窗口发送数据
        self.iICBatchProcessSignal.emit(dataDict)
        # do something
        logger.info(f"{typeValue} \t {dataObj}")

    def RecvFt4222Data(self, dictData: dict):
        """
        用于接收串口控制窗口发过来的信号或数据
        :param dictData:
        :return:
        """
        self.RecvDataHandle(dictData)

    def RecvDataHandle(self, dataDict: dict):
        """
        处理串口控制窗口发过来的信号或数据
        :param dataDict:
        :return:
        """
        typeValue = dataDict.get("type", '').strip()
        dataObj = dataDict.get('data', {})
        optionsDict = dataDict.get('options', {})
        # 收到信号
        if 'IICBatchProcess_to_' in typeValue:
            return
        elif typeValue == 'rece_protobuf':
            pass
        elif typeValue == 'read_hex':
            # 使用hexlify函数将bytes数据转换为16进制字符串
            hex_string = binascii.hexlify(dataObj).decode('utf-8').upper()
            # 插入空格
            dataObj = ' '.join(hex_string[i:i + 2] for i in range(0, len(hex_string), 2))
        elif typeValue == 'rece_ascii':
            pass
        elif '_to_IICBatchProcess' in typeValue:
            logger.info("收到其他窗口发往Plugin窗口的数据：", typeValue, dataObj)
        elif 'send_' in typeValue:
            raw_data = optionsDict.get('raw_data', '').strip()
            if len(raw_data) > 0:
                dataObj = f"{dataObj} <-- {raw_data}"
        # 其他情况
        if (not ('_' in typeValue)) and (typeValue != None):
            pass
        # do something
        # logger.info(f"{typeValue} \t {dataObj}")
        msg_id = optionsDict.get('msg_id', 0)
        expectData = optionsDict.get('expectData', '').strip()
        if (len(expectData) > 0) and (not (str(expectData) in str(dataObj))):
            tableExpectDataItem: QTableWidgetItem = self.tableWidget.item(msg_id, 8)
            tableRemarkItem: QTableWidgetItem = self.tableWidget.item(msg_id, 9)
            if tableExpectDataItem is not None:
                tableExpectDataItem.setBackground(QColor(255, 0, 0, 128))
                tableExpectDataItem.setToolTip("期望值，实际值在备注，点击刷新重新开始")
                tableRemarkItem.setBackground(QColor(255, 0, 0, 128))
                tableRemarkItem.setToolTip(tableRemarkItem.text())
                tableRemarkItem.setText(str(dataObj))
        logger.info(f"{typeValue: <9}|\t{dataObj}")

    def TimerOperateFun(self):
        """
        定时发送数据
        :return:
        """
        self.maxOperateCount = self.spinBoxOperateCount.value()
        self.curOperateCount = 0
        # self.timer_operate.stop()
        if self.checkBoxTimerOperate.isChecked():
            timeDelay = int(self.spinBoxOperateTime.text())
            self.batchWorkerThread.maxOperateCount = self.spinBoxOperateCount.value()
            self.batchWorkerThread.timeDelay = timeDelay
            if not self.batchWorkerThread.isRunning():
                self.batchWorkerThread.is_running = True
                self.batchWorkerThread.start()
            # self.timer_operate.start(timeDelay)
            self.spinBoxOperateTime.setEnabled(False)
        else:
            self.batchWorkerThread.quit()
            if self.batchWorkerThread.isRunning():
                self.batchWorkerThread.is_running = False
            self.batchWorkerThread.maxOperateCount = 0
            self.batchWorkerThread.timeDelay = 0
            self.spinBoxOperateTime.setEnabled(True)

    def HandSendFun(self, dictData: dict):
        slaveAddr = dictData.get("slaveAddr", "").strip().upper()
        if (len(slaveAddr) < 1) or ("0X" not in slaveAddr):
            QMessageBox.warning(self, "空数据", f"请输入正确的设备地址！--> {slaveAddr}")
            return None
        send_data = dictData.get("cmd_addr", "").strip() + " " + dictData.get("data_len", "").strip().upper().replace(
            '0X', '')
        send_data = send_data.strip()
        if len(send_data) < 1:
            QMessageBox.warning(self, "空数据", f"请输入要发送的内容！--> {send_data}")
            return None
        # if self.checkRemoveStr.isChecked():
        #     dataStr = eval(dataStr)
        # hex发送
        input_s = send_data
        send_list = []
        while input_s != '':
            try:
                num = int(input_s[0:2], 16)
            except ValueError:
                # QMessageBox.critical(self, 'wrong data', '请输入十六进制数据，以空格分开!')
                return None
            input_s = input_s[2:].strip()
            send_list.append(num)
        input_s = bytes(send_list)
        i2cData = {
            "slaveAddr": eval(slaveAddr),
            "writeData": input_s,
        }
        dataType = dictData.get("dataType", "hex").strip().lower()
        dictData = {"data": i2cData, "type": f"send_{dataType}",
                    "options": {"msg_id": int(dictData.get("msg_id", 0)), "raw_data": send_data}}
        self.SendDataHandle(dictData)

    def HandCtrlFun(self, dictData: dict):
        gpio = dictData.get("cmd_addr", "").strip().lower()
        if ("0X" in gpio) and (len(gpio.strip()) < 3):
            QMessageBox.warning(self, "空数据", f"请输入正确的 引脚编号（如: gpio2）！--> {gpio}")
            return None
        level = int(dictData.get("data_len", 0))
        ftData = {
            "dataAddr": gpio,
            "level": level,
        }
        operation = dictData.get("operation", "").lower()
        dictData = {"data": ftData, "type": f"{operation}_{gpio}", "msg_id": int(dictData.get("msg_id", 0))}
        self.SendDataHandle(dictData)

    def HandReadFun(self, dictData: dict):
        slaveAddr = dictData.get("slaveAddr", "").strip().upper()
        if (len(slaveAddr.strip()) < 3) or ("0X" not in slaveAddr):
            QMessageBox.warning(self, "空数据", f"请输入正确的设备地址！--> {slaveAddr}")
            return None
        dataAddr = dictData.get("cmd_addr", "").strip().upper()
        if ("0X" in dataAddr) and (len(dataAddr.strip()) < 3):
            QMessageBox.warning(self, "空数据", f"请输入正确的数据地址！--> {dataAddr}")
            return None
        dataLen = int(dictData.get("data_len", 0))
        if dataLen < 1:
            QMessageBox.warning(self, "空数据", f"请输入正确的读取长度！--> {dataLen}")
            return None
        expectData = dictData.get("expectData", "").strip().upper().replace('0X', '')
        if (len(expectData) < 1):
            QMessageBox.warning(self, "空数据", f"请输入 期望读到的数据！或者 在打印设置中去掉勾选！--> {dataLen}")
            return None
        # print('HandReadFun', dataStr)
        # if self.checkRemoveBytes.isChecked():
        #     dataStr = str(dataStr)
        input_s = dataAddr.strip().replace('0X', '')
        send_list = []
        addrLen = 0
        while input_s != '':
            addrLen += 1
            try:
                num = int(input_s[0:2], 16)
            except ValueError:
                # QMessageBox.critical(self, 'wrong data', '请输入十六进制数据，以空格分开!')
                return None
            input_s = input_s[2:].strip()
            send_list.append(num)
        input_s = bytes(send_list)
        i2cData = {
            "slaveAddr": eval(slaveAddr),
            "dataAddr": input_s,
            "dataLen": dataLen,
        }

        dataType = dictData.get("dataType", "hex").strip().lower()

        dictData = {"data": i2cData, "type": f"read_{dataType}",
                    "options": {"addrLen": addrLen, "expectData": expectData,
                                "msg_id": int(dictData.get("msg_id", 0))}}
        self.SendDataHandle(dictData)

    def SelectAllFun(self, state):
        if state:
            for row in range(self.tableWidget.rowCount()):
                item = self.tableWidget.item(row, 0)
                if item is not None:
                    item.setCheckState(Qt.CheckState.Checked)
                    item.setText("YES")
        else:
            for row in range(self.tableWidget.rowCount()):
                item = self.tableWidget.item(row, 0)
                if item is not None:
                    item.setCheckState(Qt.CheckState.Unchecked)
                    item.setText("NO")

    def OpenScriptFun(self):
        self.CleanAllScriptFun()
        # 创建文件对话框
        file_dialog = QFileDialog(self)
        # 设置文件过滤器，仅允许选择 CSV 文件
        file_dialog.setNameFilter("CSV Files (*.csv)")
        # 打开文件对话框，并获取选中的文件路径
        self.script_path, _ = file_dialog.getOpenFileName(self, "Open CSV File", "data", "CSV Files (*.csv)")
        sedMsg = '未打开任何文件'
        if self.script_path:
            self.RefreshScriptFun()
            sedMsg = '文件已经打开：{}'.format(str(self.script_path))
        dictData = {"data": sedMsg, "type": f"status_show"}
        self.SendDataHandle(dictData)

    def SaveScriptFun(self):
        sedMsg = '未保存文件'
        if self.script_path:
            # 创建一个确认退出的对话框
            reply = QMessageBox.question(self, "提示", "此操作会修改（覆盖）当前打开的脚本内容！！\n 确认操作？",
                                         QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
                                         QMessageBox.StandardButton.No)
            if reply == QMessageBox.StandardButton.Yes:
                sedMsg = '文件已保存：{}'.format(str(self.script_path))
                self.csvHandler.save_csv(filename=self.script_path, listData=self.csvHandler.runData)
        else:
            # 创建文件对话框
            file_dialog = QFileDialog(self)
            # 设置文件过滤器，仅允许选择 CSV 文件
            file_dialog.setNameFilter("CSV Files (*.csv)")
            # 打开文件对话框，并获取选中的文件路径
            self.script_path, _ = file_dialog.getSaveFileName(self, "Open CSV File", "data", "CSV Files (*.csv)")
            if self.script_path:
                self.csvHandler.save_csv(filename=self.script_path, listData=self.csvHandler.runData)
                sedMsg = '文件已保存：{}'.format(str(self.script_path))
        dictData = {"data": sedMsg, "type": f"status_show"}
        self.SendDataHandle(dictData)

    def SaveAsScriptFun(self):
        # 创建文件对话框
        file_dialog = QFileDialog(self)
        # 设置文件对话框的文件名过滤器
        file_dialog.setNameFilter("CSV Files (*.csv)")
        # 打开文件对话框，并获取要保存的文件路径
        file_path, _ = file_dialog.getSaveFileName(self, "Save CSV File", "data", "CSV Files (*.csv)")
        # print(self.filePath)
        # self.FilePath.setText(str(self.filePath[0]))
        sedMsg = '未保存文件'
        if file_path:
            self.csvHandler.save_csv(filename=file_path, listData=self.csvHandler.runData)
            sedMsg = '文件已保存：{}'.format(str(file_path))
        dictData = {"data": sedMsg, "type": f"status_show"}
        self.SendDataHandle(dictData)

    def AddScriptFun(self):
        dictData = {"checkState": "no", "shortName": "写XX", "operation": 'write', "slaveAddr": "0x20",
                    "cmd_addr": "03", "data_len": "01 33", "timeDalay": "100", "dataType": "hex", "expectData": "",
                    "remark": "写指令示例", }
        self.AddScriptData(dataDict=dictData)

    def DeleteScriptFun(self):
        rowCount = self.tableWidget.rowCount()
        for row in range(rowCount):
            delRow = rowCount - row - 1
            item = self.tableWidget.item(delRow, 0)
            if item is not None:
                # print(f"Item at row {row} in the first column: {item.checkState()}", item.text())
                if item.checkState() == Qt.CheckState.Checked:
                    self.tableWidget.removeRow(delRow)
                    self.csvHandler.runData.pop(delRow + 1)
            else:
                logger.warning(f"No item at row {delRow} in the first column")

    def OperateScriptFun(self):
        if not self.batchWorkerThread.isRunning():
            self.batchWorkerThread.timeDelay = 0
            self.batchWorkerThread.maxOperateCount = 1
            self.batchWorkerThread.is_running = True
            self.batchWorkerThread.start()

    def RefreshScriptFun(self):
        self.CleanAllScriptFun()
        if (not self.script_path) or (len(self.script_path) < 3):
            return
        self.csvHandler.read_csv(self.script_path)
        for row in self.csvHandler.csvData:
            dictData = {"checkState": row[0], "shortName": row[1], "operation": row[2], "slaveAddr": row[3],
                        "cmd_addr": row[4], "data_len": row[5], "timeDalay": row[6], "dataType": row[7],
                        "expectData": row[8], "remark": row[9], }
            self.AddScriptData(dataDict=dictData)
            # print(', '.join(row))

    def CleanAllScriptFun(self):
        self.tableWidget.setRowCount(0)
        # 保留第一行
        self.csvHandler.runData = self.csvHandler.runData[:1]

    def OnCellClicked(self, row, col):
        item = self.tableWidget.item(row, col)
        if item is not None:
            if item.column() == 0:  # 只关心第一列
                if item.checkState() == Qt.CheckState.Checked:
                    self.csvHandler.runData[item.row() + 1][item.column()] = "YES"
                    item.setText("YES")
                    # item.setCheckState(Qt.CheckState.Unchecked)
                else:
                    self.csvHandler.runData[item.row() + 1][item.column()] = "NO"
                    item.setText("NO")
                    # item.setCheckState(Qt.CheckState.Checked)
                # 执行单个指令
                rowList = self.csvHandler.runData[item.row() + 1]
                col_idx = 0
                dataDict = {}
                for col_value in rowList:
                    if col_idx == 0:
                        dataDict.update({"checkState": col_value})
                    elif col_idx == 1:
                        dataDict.update({"shortName": col_value})
                    elif col_idx == 2:
                        dataDict.update({"operation": col_value})
                    elif col_idx == 3:
                        dataDict.update({"slaveAddr": col_value})
                    elif col_idx == 4:
                        dataDict.update({"cmd_addr": col_value})
                    elif col_idx == 5:
                        dataDict.update({"data_len": col_value})
                    elif col_idx == 6:
                        dataDict.update({"timeDalay": col_value})
                    elif col_idx == 7:
                        dataDict.update({"dataType": col_value})
                    elif col_idx == 8:
                        dataDict.update({"expectData": col_value})
                    elif col_idx == 9:
                        dataDict.update({"remark": col_value})
                    col_idx += 1
                    dataDict.update({"msg_id": item.row()})
                if dataDict:
                    self.ScriptProcessFun(dataDict)
                else:
                    dictData = {"data": "数据交互-->" + str(dataDict), "type": f"cell_value"}
                    self.SendDataHandle(dictData)
            else:
                dictData = {"data": item.text(), "type": f"cell_value"}
                self.SendDataHandle(dictData)
            # print("Content of the clicked cell:", item.text())

    def OnCellChanged(self, row, col):
        item = self.tableWidget.item(row, col)
        if item is not None:
            self.csvHandler.runData[item.row() + 1][item.column()] = item.text()
            # print(f"Content of the cell at ({row}, {col}):", item.text())

    def closeEvent(self, event):
        """
        防止误触关闭程序
        :param event:
        :return:
        """
        # 创建一个确认退出的对话框
        reply = QMessageBox.question(
            self, "Confirmation", "Are you sure you want to exit?",
            QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No, QMessageBox.StandardButton.No
        )
        if reply == QMessageBox.StandardButton.Yes:
            self.CleanupSelf()
            # 用户确认退出，关闭应用
            event.accept()
        else:
            event.ignore()


# 程序入口，测试当前插件文件使用
if __name__ == "__main__":
    app = QApplication(sys.argv)
    font = QFont("宋体")
    pointsize = font.pointSize()
    font.setPixelSize(int(pointsize * 90 / 72))
    app.setFont(font)
    myWindow = IICBatchProcessWindow()
    myWindow.show()
    sys.exit(app.exec())
